home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / drivers.arc / NI5210.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-10-20  |  18.5 KB  |  708 lines

  1. version    equ    3
  2.  
  3.     include    defs.asm    ;SEE ENCLOSED COPYRIGHT MESSAGE
  4.  
  5. ;Ported from Tim Krauskopf's micnet.asm, an assembly language
  6. ;driver for the MICOM-Interlan NI5210 by Russell Nelson.  Any bugs
  7. ;are due to Russell Nelson.
  8.  
  9. ;/*
  10. ;*  NCSA Telnet source code
  11. ;*  National Center for Supercomputing Applications
  12. ;*  November 1, 1987
  13. ;*  (C) Copyright 1987 The Board of Trustees of the University of Illinois
  14. ;*
  15. ;*  Permission is granted to any individual or institution to use, copy,
  16. ;*  modify, or redistribute this software and its documentation provided
  17. ;*  this notice and the copyright notices are retained.  This software
  18. ;*  may not be distributed for profit, either in original form or in
  19. ;*  derivative works.  The University of Illinois makes no representations
  20. ;*  about the suitability of this software for any purpose.  
  21. ;*  THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY,
  22. ;*  EITHER EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  23. ;*  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY
  24. ;*  OF FITNESS FOR A PARTICULAR PURPOSE.
  25. ;*/
  26.  
  27. code    segment    byte public
  28.     assume    cs:code, ds:code
  29.  
  30. ;
  31. ;  Equates for controlling the MICOM board
  32. ;
  33. ;  I/O addresses, writing anything in AL trips these gates
  34. ;
  35. ;  First six addresses are the EPROM board Ether address (read)
  36. ;
  37. IORESET    EQU    0        ; reset the board
  38. IOCA    EQU    1        ; execute command which is in SCB
  39. IODIS    EQU    2        ; disable network connect
  40. IOENA    EQU    3        ; enable network
  41. IOINTON    EQU    4        ; enable interrupts
  42. IOINTOF    EQU    5        ; disable interrupts, '586 thinks it still ints
  43. ;
  44. ;  Structure elements specific to the Intel 82586 chip
  45. ;
  46. BDBASE    EQU    1874        ; base address for 30 buffer descriptors
  47. BUFBASE    EQU    2174        ; base address for 30 200 byte buffers
  48. BDSTAT    EQU    0        ; status word in BD
  49. BDLINK    EQU    2        ; 16pointer to next BD
  50. BDPTR    EQU    4        ; 24pointer to actual buffer
  51. BDSIZE    EQU    8        ; size of the buffer
  52. ;
  53. SCB    EQU    10        ; system control block base
  54. SSTAT    EQU    0        ; status word for SCB
  55. SCOM    EQU    2        ; command word in SCB
  56. SCBL    EQU    4        ; 16pointer to command block list
  57. SRFA    EQU    6        ; 16pointer to receive frame list
  58. SERRS    EQU    8        ; 4 words of error counts
  59. ;
  60. FDBASE    EQU    1214        ; base addr for 30 frame descriptors
  61. FDSTAT    EQU    0        ; status word for frame
  62. FDEOL    EQU    2        ; end of FD list flag
  63. FDLINK    EQU    4        ; 16pointer to next FD
  64. FDPTR    EQU    6        ; 16pointer to list of BD's
  65. ;
  66. TSTAT    EQU    0        ; status word for xmit
  67. TCOM    EQU    2        ; command to transmit
  68. TLINK    EQU    4        ; 16pointer to next command (always ffff)
  69. TPTR    EQU    6        ; 16pointer to xmit TBD
  70. TTRIES    EQU    8        ; number of transmit retries
  71. ;
  72. SCPTR    EQU    01ff6h        ; hardwired address for SCP
  73. ISCPTR    EQU    01feeh        ; my address for ISCP, points to SCB
  74. CCBPTR    EQU    26        ; offset of configure command block
  75. TCBPTR    EQU    44        ; xmit CB offset
  76. TBDPTR    EQU    60        ; xmit BD offset
  77. TBUFPTR    EQU    68        ; xmit buffer offset
  78.  
  79.  
  80. ;
  81. ;  Data segment
  82. ;
  83.  
  84.     public    int_no
  85. int_no        db    2,0,0,0        ; interrupt number.
  86. io_addr        dw    0360h,0        ; I/O address for card (jumpers)
  87. base_addr    dw      0d000h,0    ; base segment for board (jumper set)
  88.  
  89.     public    driver_class, driver_type, driver_name
  90. driver_class    db    1        ;from the packet spec
  91. driver_type    db    11        ;from the packet spec
  92. driver_name    db    "NI5210",0    ;name of the driver.
  93.  
  94. firstfd        dw    FDBASE        ; start of FD queue
  95. lastfd        dw    0        ; end of the FD chain
  96. lastbd        dw    0        ; end of the BD chain
  97.  
  98.  
  99.     public    send_pkt
  100. send_pkt:
  101. ;enter with ds:si -> packet, cx = packet length.
  102. ;exit with nc if ok, or else cy if error, dh set to error number.
  103.     assume    ds:nothing
  104.     mov    ax,base_addr
  105.     mov    es,ax        ; base for board
  106.  
  107.     mov    dx,cx        ; save a copy, might be less than 60, ok
  108.  
  109.     cmp    dx,RUNT        ; minimum length for Ether
  110.     jnb    oklen
  111.     mov    dx,RUNT        ; make sure size at least RUNT
  112. oklen:
  113.     mov    di,TBUFPTR    ; start of xmit buffer
  114.  
  115. ;
  116. ;  check for previous xmit
  117. ;
  118. xwait:
  119.     mov    bx,word ptr es:[SCB+SCOM]    ; is command zeroed yet?
  120.     or    bx,bx
  121.     jnz    xwait                ; not there yet, wait for it
  122. ;
  123. ;  move the data using word moves.
  124. ;
  125.     shr    cx,1
  126.     jnc    send_even
  127.     movsb
  128. send_even:
  129.     rep    movsw                ; copy into buffer
  130. ;
  131. ;  put the correct size into the TDB
  132. ;
  133.     or    dx,08000h            ; end of frame bit flag
  134.     mov    word ptr es:[TBDPTR],dx        ; store it
  135.     mov    word ptr es:[TCBPTR],0        ; zero status wd
  136.     mov    word ptr es:[TCBPTR+TCOM],08004h; xmit command in TCB
  137.     mov    word ptr es:[SCB+SCOM],0100h    ; execute command
  138.  
  139.     loadport
  140.     setport    IOCA
  141.     out    dx,al        ; issue CA to get it going
  142.  
  143.     ret
  144.  
  145.  
  146.     public    get_address
  147. get_address:
  148. ;get the address of the interface.
  149. ;enter with es:di -> place to get the address, cx = size of address buffer.
  150. ;exit with nc, cx = actual size of address, or cy if buffer not big enough.
  151.     assume    ds:code
  152.     cmp    cx,EADDR_LEN            ;make sure that we have enough room.
  153.     jb    get_address_2
  154.     mov    cx,EADDR_LEN
  155.     mov    dx,io_addr        ; Get our IO base address.
  156.     cld
  157. get_address_1:
  158.     in    al,dx            ; get a byte of the eprom address
  159.     stosb                ; put it away
  160.     inc    dx            ; next register
  161.     loop    get_address_1        ; go back for rest
  162.     mov    cx,EADDR_LEN
  163.     clc
  164.     ret
  165. get_address_2:
  166.     stc
  167.     ret
  168.  
  169.  
  170.     public    reset_interface
  171. reset_interface:
  172. ;reset the interface.
  173. ;we don't do anything.
  174.     ret
  175.  
  176.  
  177. ;called when we want to determine what to do with a received packet.
  178. ;enter with cx = packet length, es:di -> packet type.
  179.     extrn    recv_find: near
  180.  
  181. ;called after we have copied the packet into the buffer.
  182. ;enter with ds:si ->the packet, cx = length of the packet.
  183.     extrn    recv_copy: near
  184.  
  185.     extrn    count_in_err: near
  186.     extrn    count_out_err: near
  187.  
  188.     public    recv
  189. recv:
  190. ;called from the recv isr.  All registers have been saved, and ds=cs.
  191. ;Upon exit, the interrupt will be acknowledged.
  192.     mov    ds,base_addr    ; base for board
  193.     assume    ds:nothing
  194.  
  195.     mov    ax,ds:[SCB+SSTAT]    ;get the status.
  196. recv_isr_1:
  197.     cmp    word ptr ds:[SCB+SCOM],0 ;are we done yet?
  198.     jne    recv_isr_1        ;no -- keep waiting.
  199.  
  200.     and    ax,0f000h        ;isolate the ACK bits.
  201.     mov    ds:[SCB+SCOM],ax    ;make a command to
  202.                     ;acknowledge the interrupt.
  203.     loadport
  204.     setport    IOCA
  205.     out    dx,al
  206.  
  207. ;  Get whatever packets are on the board
  208. ;
  209.     mov    bx,firstfd    ; get addr of first FD in list
  210. ;
  211. ;
  212. ckframe:
  213.     mov    ax,[bx+FDSTAT]    ; status word of frame
  214.     test    ax,08000h    ; frame written?
  215.     jnz    okframe
  216.  
  217.     jmp    ru_start    ; no, restore receiver if necessary
  218. ptrupdate_j_1:
  219.     jmp    ptrupdate
  220. frame_bad_j_1:
  221.     call    count_in_err
  222.     jmp    frame_bad
  223.  
  224. ;  we have a frame, read it in
  225. ;
  226. okframe:
  227.  
  228.     test    ax,02000h        ;check frame OK bit
  229.     jz    frame_bad_j_1        ;bad, fix it.
  230.     mov    si,[bx+FDPTR]        ;get pointer to buffer descriptor
  231.     xor    cx,cx            ;start with zero bytes.
  232. countbuf:                ;es:di is already set to receive packet
  233.     mov    dx,si            ;save a copy of current BD ptr
  234.     mov    ax,[si+BDSTAT]        ;get status and count word for BD
  235.     test    ax,04000h        ;is count field there?
  236.     jz    ptrupdate_j_1        ;no - we give up here.
  237.     add    cl,al            ;add the count into cx.
  238.     adc    ch,0
  239.     mov    si,[si+BDLINK]        ;go to next BD in list
  240.     test    ax,8000h        ;is this the last frame?
  241.     je    countbuf        ;no - keep counting.
  242.  
  243.     mov    ax,0            ;we have the size needed.
  244.     push    bx
  245.     push    cx
  246.  
  247.     mov    ax,cs            ;we need ds = code.
  248.     mov    ds,ax
  249.     assume    ds:code
  250.  
  251.     mov    es,base_addr        ;get a pointer to their type.
  252.     mov    di,es:[bx+FDPTR]    ;get pointer to buffer descriptor
  253.     mov    di,es:[di+BDPTR]    ;get offset of data
  254.     add    di,EADDR_LEN+EADDR_LEN    ;skip the ethernet addreses and
  255.                     ;  point to the packet type.
  256.  
  257.     call    recv_find        ;look up our type.
  258.  
  259.     pop    cx
  260.     pop    bx
  261.     mov    ds,base_addr        ;restore ds to the board.
  262.     assume    ds:nothing
  263.  
  264.     mov    ax,es            ;is this pointer null?
  265.     or    ax,di
  266.     je    ptrupdate        ;yes - just free the frame.
  267.  
  268.     push    cx
  269.     push    es            ;remember where the buffer pointer is.
  270.     push    di
  271.  
  272.     mov    si,[bx+FDPTR]        ;get pointer to buffer descriptor
  273. copybuf:
  274.     mov    dx,si            ;save a copy of current BD ptr
  275.     xor    ch,ch            ;200 bytes is largest this can be
  276.     mov    cl,[si+BDSTAT]        ;get count word for BD
  277.     mov    si,[si+BDPTR]        ;get offset of data
  278.     shr    cx,1            ;move the data using a word move.
  279.     jnc    recv_even
  280.     movsb
  281. recv_even:
  282.     rep    movsw            ;copy the bytes from this packet segment
  283.     mov    si,dx            ;get back current BD ptr
  284.     test    [si+BDSTAT],8000h    ;check EOF bit
  285.     mov    si,[si+BDLINK]        ;go to next BD in list
  286.     jz    copybuf            ;not done, keep copying it.
  287.  
  288.     pop    si            ;now give the frame to the client.
  289.     pop    ds
  290.     pop    cx
  291.     assume    ds:nothing
  292.  
  293.     call    recv_copy
  294.  
  295.     jmp    short ptrupdate
  296.  
  297. frame_bad:
  298. ;
  299. ;  we are done with the frame, do the list management
  300. ;
  301. ptrupdate:
  302.     push    cs
  303.     pop    ds
  304.     assume    ds:code
  305.     mov    es,base_addr        ; reload board segment
  306.  
  307.     mov    si,es:[bx+FDPTR]    ; first BD in frame list
  308. nextbd:
  309.     mov    cx,es:[si+BDSTAT]    ; count word for BD, EOF bit
  310.     test    cx,08000h        ; EOF bit, if set, save si in lastbd
  311.     jnz    dolastbd
  312.     mov    word ptr es:[si+BDSTAT],0 ; clear status word, EOF bit
  313.     cmp    si,lastbd        ; see if we are wrapping
  314.     jz    dolastbd        ; yes, just undo it
  315.     mov    si,es:[si+BDLINK]    ; follow link
  316.     jmp    nextbd
  317. dolastbd:
  318.     mov    di,lastbd        ; where end of BD list is now
  319.     mov    lastbd,si        ; store last known BD
  320.     mov    word ptr es:[si+BDSIZE],08000h+200    ; end of list here
  321.     mov    word ptr es:[si+BDSTAT],0 ; clear status word, EOF bit
  322. ; size field for not end of list
  323.     mov    word ptr es:[di+BDSIZE],200    ; remove old end-of-list
  324.  
  325. ;
  326. ;  update the FD list flags, new end-of-list
  327. ;
  328.     mov    word ptr es:[bx+FDEOL],08000h    ; store new EOL
  329.     mov    word ptr es:[bx+FDSTAT],0    ; clear status word for frame
  330.     mov    di,lastfd        ; get old end-of-list
  331.     mov    word ptr es:[di+FDEOL],0 ; zero old one
  332.     mov    lastfd,bx        ; update stored pointer
  333.     mov    si,es:[bx+FDLINK]    ; where next fd is
  334.     mov    firstfd,si        ; store that info for next time
  335.  
  336. ru_start:
  337. ; re-start receive unit
  338. ;
  339. ;  check to see if the receiver went off because of no resources
  340. ;  and restart receiver if necessary
  341. ;
  342.     call    count_out_err
  343.  
  344.     push    cs
  345.     pop    ds
  346.     mov    es,base_addr
  347.     mov    ax,es:[SCB+SSTAT]    ; status word for SCB
  348.     and    ax,070h        ; receiver status
  349.     cmp    al,020h        ; receiver has no resources
  350.     jnz    hasres
  351. ;
  352. ;  setup lists for starting the RU on the chip
  353. ;  we know that there isn't anything in the buffer that we want
  354. ;
  355.  
  356.     mov    bx,firstfd    ; get first FD on free list (assume free)
  357.     mov    word ptr es:[SCB+SRFA],bx    ; put into SCB
  358.     mov    si,lastbd    ; pointer to a BD, end of chain
  359.     mov    ax,word ptr es:[si+BDLINK]    ; pointer to next BD
  360.     mov    word ptr es:[bx+FDPTR],ax    ; set to start of BDs
  361. ;
  362. ;
  363. ;  Start the RU, doesn't need CB, only SCB parms.
  364. ;   command, to start receiving again
  365. ;
  366.     mov    word ptr es:[SCB+SSTAT],0    ; clear status word
  367.     mov    word ptr es:[SCB+SCOM],010h    ; start RU
  368.     loadport
  369.     setport    IOCA
  370.     out    dx,al
  371. hasres:
  372.     ret
  373.  
  374.  
  375. end_resident    label    byte
  376.  
  377.     public    usage_msg
  378. usage_msg    db    "usage: ni5210 <packet_int_no> <int_no> <io_addr> <base_addr>",CR,LF,'$'
  379.  
  380.     public    copyright_msg
  381. copyright_msg    db    "Packet driver for the MICOM-Interlan NI5210, version ",'0'+version,CR,LF
  382.         db    "Portions Copyright 1988 The Board of Trustees of the University of Illinois",CR,LF,'$'
  383.  
  384. no_5210_msg    db    "No 5210 found at that address.",CR,LF,'$'
  385. timeout_msg    db    "Timed out while initializing 5210.",CR,LF,'$'
  386. int_no_name    db    "Interrupt number ",'$'
  387. io_addr_name    db    "I/O port ",'$'
  388. base_addr_name    db    "Memory address ",'$'
  389.  
  390.     extrn    set_recv_isr: near
  391.  
  392.  
  393. ;enter with si -> argument string, di -> word to store.
  394. ;if there is no number, don't change the number.
  395.     extrn    get_number: near
  396.  
  397. ;enter with dx:ax = number to print.
  398.     extrn    hexout: near, decout: near
  399.  
  400.     public    parse_args
  401. parse_args:
  402.     mov    di,offset int_no
  403.     mov    bx,offset int_no_name
  404.     call    get_number
  405.     mov    di,offset io_addr
  406.     mov    bx,offset io_addr_name
  407.     call    get_number
  408.     mov    di,offset base_addr
  409.     mov    bx,offset base_addr_name
  410.     call    get_number
  411.     ret
  412.  
  413.  
  414. timeout_error:
  415.     mov    dx,offset timeout_msg
  416.     jmp    short error
  417. no_5210_error:
  418.     mov    dx,offset no_5210_msg
  419. error:
  420.     mov    ah,9
  421.     int    21h
  422.     stc
  423.     ret
  424.  
  425. ;
  426. ;  data for configuring and setting up the MICOM board
  427. ;
  428. ;  chip always looks at SCP for config info which points to ISCP for the
  429. ;  pointer to the CONTROL BLOCK which handles everything from there.
  430. ;  Kind of indirect, but it works.
  431. ;
  432. SCP    DB    1        ; bus use flag
  433.     DB    5 DUP(0)    ; unused
  434.     DW    ISCPTR        ; 24pointer to ISCP offset
  435.     DW    0        ; high part
  436. ;
  437. ; Intermediate SCP
  438. ;
  439. ISCP    DW    1        ; busy flag
  440.     DW    SCB        ; 16pointer to SCB
  441.     DW    0,0        ; base for all 16 pointers, lo, hi
  442.                 ; board is hardwired to 0 for these values
  443. ;
  444. ; Configuration block for 82586, this comprises one config command
  445. ;  Parameters taken from MICOM driver
  446. ;
  447. CBCONF    DW    0        ; status word
  448.     DW    8002H        ; end of command list + configure command
  449.     DW    0ffffh        ; link to next command (not used)
  450.     DW    080CH        ; fifo=8, byte count=C
  451.     DW    2E00H        ; important! Addr (AL) not inserted on the fly!
  452.     DW    6000H        ; IFS = 60h
  453.     DW    0F200H        ; retry=F, slot time=200h
  454.     DW    0        ; flags, set to 1 for promiscuous
  455.     DW    40H        ; min frame length=40h
  456. ;
  457. ; CB for xmit, followed by BD for xmit, copied together
  458. ;
  459. TCB    DW    0        ; status word
  460.     DW    08004H        ; command word for xmit + EL
  461.     DW    0ffffh        ; no command link
  462.     DW    TBDPTR        ; 16pointer to xmit BD
  463.     DW    0,0,0,0        ; no addressing used here
  464. ;
  465. ; BD template for xmit
  466. TBD    DW    0
  467.     DW    0        ; next BD pointer, unused
  468.     DW    TBUFPTR        ; 24pointer to xmit buffer
  469.     DW    0        ; high part of pointer
  470.  
  471.  
  472.     public    etopen
  473. etopen:
  474. ;  Initialize the Ethernet board, set receive type.
  475. ;
  476. ;  check for correct EPROM location
  477. ;
  478.     mov    dx,io_addr    ; i/o address
  479.     add    dx,EADDR_LEN    ; look past the ethernet address.
  480.     in    al,dx
  481.     mov    bl,al        ; assemble pattern to check
  482.     inc    dx
  483.     in    al,dx
  484.     mov    bh,al
  485.     cmp    bx,05500h        ; pattern known to be there in ROM
  486.     jz    have_5210
  487.     jmp    no_5210_error        ;not there -- no 5210.
  488. have_5210:
  489. ;
  490. ;  Initialize MICOM 5210
  491. ;
  492. ;  Install 8K SCP, we only use 8K bytes no matter what
  493. ;
  494.     mov    es,base_addr    ; set to base address
  495.     mov    di,SCPTR
  496.     mov    si,offset SCP    ; get pre-set values
  497.     mov    cx,5        ; 5 words
  498.     rep    movsw        ; install SCP
  499. ;
  500. ;  Install 16K SCP, just in case they have that much.
  501. ;
  502.     mov    si,offset SCP    ; get pre-set values
  503.     mov    di,SCPTR+2000h    ; offset for 16K board
  504.     mov    cx,5        ; 5 words
  505.     rep    movsw        ; install SCP
  506. ;
  507. ;  Intermediate SCP
  508. ;
  509.     mov    si,offset ISCP    ; addr of pre-set values
  510.     mov    di,ISCPTR
  511.     mov    cx,4        ; 4 words
  512.     rep    movsw        ; install ISCP
  513. ;
  514. ;  Turn off interrupts, I don't want them
  515. ;
  516.     loadport
  517.     setport    IORESET
  518.     out    dx,al        ; reset the chip
  519. ;
  520. ;  Issue a CA to initialize the chip after reset
  521. ;
  522.     setport    IOCA
  523.     out    dx,al        ; CA
  524. ;
  525. ;  Disconnect from network
  526.     setport    IODIS
  527.     out    dx,al
  528. ;
  529. ;  configure 82586
  530. ;
  531.     mov    si,offset CBCONF    ; configure command
  532.     mov    di,CCBPTR        ; where command will reside
  533.     mov    cx,9
  534.     rep    movsw            ; copy to board
  535. ;
  536. ;  issue the configure command
  537. ;
  538.     mov    word ptr es:[SCB+SCOM],0100h    ; do-command command
  539.     mov    word ptr es:[SCB+SCBL],CCBPTR    ; where conf command is
  540.     mov    word ptr es:[SCB+SERRS],0    ; zero errs field
  541.     mov    word ptr es:[SCB+SERRS+2],0    ; zero errs field
  542.     mov    word ptr es:[SCB+SERRS+4],0    ; zero errs field
  543.     mov    word ptr es:[SCB+SERRS+6],0    ; zero errs field
  544.     setport    IOCA
  545.     out    dx,al            ; send it
  546.     xor    cx,cx            ; timeout
  547. waitconf:
  548.     mov    ax,word ptr es:[CCBPTR]    ; get status word
  549.     test    ax,08000h        ; is command complete?
  550.     loopz    waitconf
  551.     jnz    confok
  552.     jmp    timeout_error
  553. confok:
  554. ;
  555. ;  Next step, load our address into the board
  556. ;     reuses the space that the configure command used, with different command
  557. ;
  558.     mov    di,CCBPTR        ; start of config command block
  559.     xor    ax,ax
  560.     stosw                ; zero status word for commmand
  561.     mov    ax,8001h        ; IA setup command + EL
  562.     stosw
  563.     xor    ax,ax
  564.     dec    ax
  565.     stosw                ; set link value to -1 (unused)
  566. ;
  567. ;  move my addr onto board location inside IA command
  568. ;
  569.     mov    dx,io_addr        ; Get our IO base address
  570.     mov    cx,EADDR_LEN
  571. store_address_1:
  572.     in    al,dx            ; get a byte of the eprom address
  573.     stosb                ; put it away
  574.     inc    dx            ; next register
  575.     loop    store_address_1        ; go back for rest
  576.  
  577. ;
  578. ;  start the IA setup command
  579. ;
  580.     mov    word ptr es:[SCB+SCOM],0100h    ; do-command command
  581.     loadport
  582.     setport    IOCA
  583.     out    dx,al            ; send it
  584.     xor    cx,cx            ; timeout
  585. waitia:
  586.     mov    ax,word ptr es:[CCBPTR]    ; get status word
  587.     test    ax,08000h        ; is command complete?
  588.     loopz    waitia
  589.     jnz    iaok
  590.     jmp    timeout_error
  591. iaok:
  592. ;
  593. ;  IA sent, setup all of the other data structures on the board
  594. ;  start with xmit command descriptors
  595. ;
  596.     mov    si,offset TCB        ; template for xmit
  597.     mov    di,TCBPTR        ; where it goes on board
  598.     mov    cx,12            ; copies CB and BD for xmit
  599.     rep    movsw
  600. ;
  601. ;  Set up frame and buffer descriptors, 30 each
  602. ;
  603.     mov    cx,30            ; # of FDs
  604.     mov    di,FDBASE        ; base addr for FDs
  605. fdloop:
  606.     xor    ax,ax
  607.     mov    bx,di            ; save pointer
  608.     stosw                ; clear status wd
  609.     stosw                ; clear EL field
  610.     add    bx,22            ; points to next one
  611.     mov    es:[di],bx        ; put in link ptr
  612.     inc    di
  613.     inc    di
  614.     dec    ax
  615.     stosw                ; clear BD ptr to -1
  616.     add    di,14
  617.     loop    fdloop
  618.  
  619.     sub    di,20            ; point back to last EL field
  620.     mov    ax,08000h        ; end of list
  621.     stosw                ; put into last FD
  622.     sub    di,4            ; back to beginning of last FD
  623.     mov    lastfd,di        ; save the pointer
  624.     mov    word ptr es:[di+FDLINK],FDBASE    ; make list circular,
  625.                         ; from last to first
  626.  
  627.     mov    ax,BDBASE        ; first BD
  628.     mov    word ptr es:[FDBASE+FDPTR],ax    ; put it in the first FD frame
  629. ;
  630. ;  now BDs
  631.     mov    cx,30
  632.     mov    di,BDBASE        ; start of BD area
  633.     mov    dx,BUFBASE        ; start of buffer area
  634. bdloop:
  635.     xor    ax,ax
  636.     mov    bx,di            ; save pointer
  637.     stosw                ; zero status field
  638.     add    bx,10            ; point to next record
  639.     mov    es:[di],bx        ; put in link ptr
  640.     inc    di
  641.     inc    di
  642.     mov    es:[di],dx        ; address of buffer, lo part
  643.     inc    di
  644.     inc    di
  645.     stosw                ; zero out high part
  646.     mov    ax,200
  647.     stosw                ; store length field
  648.     add    dx,ax            ; add in length of buffer, updates ptr
  649.     loop    bdloop
  650.  
  651.     sub    di,2            ; back to last BD size field
  652.     mov    ax,08000h+200        ; end of list + 200
  653.     stosw                ; mark end of list
  654.     sub    di,8            ; back to last BDLINK field
  655.     mov    ax,BDBASE
  656.     stosw                ; put link to beginning of list here
  657.     sub    di,4            ; back to beginning of last BD
  658.     mov    lastbd,di        ; save pointer to end of list
  659. ;
  660. ;  minor detail, but important
  661. ;  Change SCB command block pointer to setup for xmit commands
  662. ;      = only commands needed when operational
  663. ;
  664.     mov    word ptr es:[SCB+SCBL],TCBPTR    ; where xmit command is
  665. ;
  666. ;  configure to connect to network
  667. ;
  668.     loadport
  669.     setport    IOENA            ; enable network
  670.     out    dx,al            ; any al value
  671. ;
  672. ;  Start the RU, doesn't need CB, only SCB parms.
  673. ;   command, to start receiving
  674. ;
  675.     mov    word ptr es:[SCB],0        ; clear status word
  676.     mov    word ptr es:[SCB+SRFA],FDBASE    ; set to frame descriptors
  677.     mov    word ptr es:[SCB+SCOM],010h    ; start RU
  678.     setport    IOCA
  679.     out    dx,al
  680.  
  681. ;
  682. ; Now reset CX, FR, CNA, and RNR so that we don't get a spurious interrupt.
  683. ;
  684. store_ack_1:
  685.     cmp    word ptr es:[SCB+SCOM],0 ;are we done yet?
  686.     jne    store_ack_1        ;no -- keep waiting.
  687.  
  688.     mov    ax,es:[SCB+SSTAT]    ;get the status.
  689.     and    ax,0f000h        ;isolate the ACK bits.
  690.     mov    es:[SCB+SCOM],ax    ;make a command to
  691.                     ;acknowledge the interrupt.
  692.  
  693.     setport    IOCA
  694.     out    dx,al
  695.  
  696. ;
  697. ; Now hook in our interrupt
  698. ;
  699.     call    set_recv_isr
  700.     mov    dx,offset end_resident
  701.     clc
  702.     ret
  703.  
  704.  
  705. code    ends
  706.  
  707.     end
  708.